package com.swh.gameproject;

import androidx.appcompat.app.AppCompatActivity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    private EditText ipPort;
    private static ProgressBar progressBar;
    private static TextView redCount;
    private static TextView blueCount;
    private static TextView myFrequency;
    private static TextView myCount;
    private static TextView ready;

    private static String redOrBlue="NO";
    private static boolean weWin=false;
    private static AlertDialog.Builder builder;

    private static BufferedReader bufferedReader;
    private static BufferedWriter bufferedWriter;
    private Socket socket=null;
    private SensorManagerHelper sensorHelper;
    private int shakeCount=0;
    private boolean isPlaying=false;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * onCreate函数是获取界面控件对象，实现按钮的点击函数
         */
        progressBar=findViewById(R.id.progressBar);
        redCount=findViewById(R.id.red_count);
        blueCount=findViewById(R.id.blue_count);
        myFrequency=findViewById(R.id.my_frequency);
        myCount=findViewById(R.id.my_count);
        ready=findViewById(R.id.ready);
        Button matchButton=findViewById(R.id.match_button);
        Button joinButton=findViewById(R.id.join_button);
        ipPort=findViewById(R.id.ip_port);
        handler=new MyHandler();
        builder=new AlertDialog.Builder(MainActivity.this);

        matchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isPlaying)
                    ready.setText("正在游戏中...");
                else
                    new MatchJoin("match").start();

            }
        });
        joinButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isPlaying)
                    ready.setText("正在游戏中...");
                else
                    new MatchJoin("join").start();
            }
        });

    }

    @Override
    public void onBackPressed(){
        new Thread(){
            @Override
            public void run(){
                sendMessage("exit");
            }
        }.start();
        super.onBackPressed();
    }

    public static void sendMessage(String msg){
        try{
            bufferedWriter.write(msg+"\n");
            bufferedWriter.flush();
        }catch(Exception e){
            e.printStackTrace();
        }
    }


    public String readMessage(){
        try{
            String getMessage=bufferedReader.readLine();
            return getMessage;
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }

    public void handleMessage(int what,String msg){
        Message message=new Message();
        message.what=what;
        message.obj=msg;
        handler.sendMessage(message);
    }

    /**
     * checkShake是检测摇晃，结束时游戏数据的结算
     */
    public void checkShake(){
        sensorHelper = new SensorManagerHelper(this);
        sensorHelper.setOnShakeListener(new SensorManagerHelper.OnShakeListener() {
            @Override
            public void onShake() {
                new Thread(){
                    @Override
                    public void run(){
                        sendMessage("shake");
                    }//传感器监听实在主线程，所以发送数据的开启一个新线程
                }.start();
                shakeCount+=1;
                myCount.setText("我的次数:"+shakeCount);
            }
        });
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                new Thread(){
                    @Override
                    public void run(){
                        sendMessage("exit");
                        try {
                            socket.close();
                            socket=null;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }//handle实在主线程，所以发送数据的开启一个新线程
                }.start();
                sensorHelper.stop();
                if(weWin) ready.setText("我方获胜");
                else ready.setText("我方失败");
                float frequency=shakeCount/10;
                String strFre=String.valueOf(frequency);
                myFrequency.setText("我的手速:"+frequency+"次/秒");

                Runnable runnable=new Runnable() {
                    @Override
                    public void run() {
                        isPlaying=false;//清算完成才算结束，此时才能再次匹配
                        shakeCount=0;
                        redOrBlue="NO";
                        progressBar.setProgress(100);
                        redCount.setText("红方次数:0");
                        blueCount.setText("蓝方次数:0");
                        myCount.setText("我的次数:0");
                        myFrequency.setText("我的频率:0次/秒");
                        ready.setText("");
                    }
                };//游戏结束10秒后清理界面数据
                handler.postDelayed(runnable,10000);
            }
        }, 10000);//10秒后停止游戏
    }


    private class MatchJoin extends Thread{
        private String select;

        public MatchJoin(String s){
            select=s;
        }

        /**
         * connectSever函数是连接服务器
         */
        public void connectSever(){
            String ipport=ipPort.getText().toString();
            if(ipport==null){
                handleMessage(10,null);//请输入服务器和端口号
                return;
            }
            int index=ipport.indexOf(':');
            if(index==-1) index=ipport.indexOf('：');
            if(index==-1) {
                handleMessage(8,null);//地址或端口输入错误
                return;
            }
            String serverIp=ipport.substring(0,index);
            int serverPort= Integer.parseInt(ipport.substring(index+1));
            try {
                socket=new Socket(serverIp,serverPort);
                bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            } catch (IOException e) {
                handleMessage(9,null);//服务器连接失败，检查输入地址
                e.printStackTrace();
            }
        }

        /**
         * matchSever函数是开始匹配按钮的内容
         * @return
         */
        public boolean matchSever(){
            if(socket==null||socket.isClosed())
                connectSever();
            if (socket==null) return false;
            if(socket.isConnected()){
                handleMessage(11,null);//正在寻找旗鼓相当的对手...
                sendMessage("match\n");
                return true;
            }else{
                handleMessage(12,null);//连接已断开，退出重进
                return false;
            }
        }

        /**
         * joinSever函数是加入比赛按钮的内容
         * @return
         */
        public boolean joinSever(){
            if(socket==null||socket.isClosed())
                connectSever();
            if(socket==null) return false;
            if(socket.isConnected()){
                handleMessage(14,null);
                return true;
            }else{
                handleMessage(12,null);
                return false;
            }
        }

        /**
         * run函数是接收服务器的数据
         */
        @Override
        public void run(){
            if(select.equals("match")&&!matchSever()) return;
            if(select.equals("join")&&!joinSever()) return;
            while(true){
                String getMessage=readMessage();
                if(getMessage==null||getMessage.length()<2)
                    continue;
                switch (getMessage.substring(0,2)) {
                    case "RE":
                        redOrBlue="RE";
                        handleMessage(0,null);
                        break;
                    case "BL":
                        redOrBlue="BL";
                        handleMessage(1,null);
                        break;
                    case "MS":
                        isPlaying = true;
                        try {
                            Thread.sleep(1500);
                            handleMessage(2,null);
                            Thread.sleep(1500);
                            handleMessage(3,null);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        checkShake();//handler是否会阻塞该线程，从而没法没服务器数据
                        break;
                    case "MF":
                        handleMessage(4,null);
                        break;
                    case "JS":
                        isPlaying=true;
                        handleMessage(5,null);
                        checkShake();
                        break;
                    case "JF":
                        handleMessage(6,null);
                        break;
                    case "DA":
                        handleMessage(7,getMessage);
                        if(isPlaying==false) return;//结束游戏时结束该线程
                        break;
                    default:
                        handleMessage(13,null);
                }
            }
        }
    }

    /**
     * 一下整个MyHandler根据接收的数据更新界面
     */
    private static class MyHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    redCount.setText("我方次数:0");
                    blueCount.setText("蓝方次数:0");
                    break;
                case 1:
                    redCount.setText("红方次数:0");
                    blueCount.setText("0:我方次数");
                    break;
                case 2:
                    ready.setText("准备");
                    break;
                case 3:
                    ready.setText("开始");
                    break;
                case 4:
                    ready.setText("匹配失败，加入试试");
                    break;
                case 5:
                    ready.setText("加入成功，开始摇吧");
                    break;
                case 6:
                    ready.setText("加入失败，匹配试试");
                    break;
                case 7://DA xxx-xxx
                    String getMessage=msg.obj.toString();
                    int index=getMessage.indexOf('-');
                    String rCount=getMessage.substring(2,index);
                    String bCount=getMessage.substring(index+1);
                    int increase=100+(Integer.parseInt(rCount)-Integer.parseInt(bCount));
                    progressBar.setProgress(increase);
                    if(redOrBlue.equals("RE")){
                        if(increase>100) weWin=true;
                        else weWin=false;
                        redCount.setText("我方次数:"+rCount);
                        blueCount.setText(bCount+":蓝方次数");
                    }else if(redOrBlue.equals("BL")){
                        if(increase>100) weWin=false;
                        else weWin=true;
                        redCount.setText("红方次数:"+rCount);
                        blueCount.setText(bCount+":我方次数");
                    }
                    break;
                case 8:
                    ready.setText("地址或端口输入错误");
                    break;
                case 9:
                    ready.setText("服务器连接失败，检查输入地址");
                    break;
                case 10:
                    ready.setText("请输入服务器和端口号");
                    break;
                case 11:
                    ready.setText("正在寻找旗鼓相当的对手...");
                    break;
                case 12:
                    ready.setText("连接已断开，推出重进");
                    break;
                case 13:
                    ready.setText("服务器数据无法识别");
                    break;
                case 14:
                    builder.setTitle("请选择加入某一方");
                    final String []items=new String[]{"RED","BLUE"};
                    builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            redOrBlue=items[which].substring(0,2);
                            dialog.dismiss();
                        }
                    });
                    builder.show();
                    new Thread(){
                        @Override
                        public void run(){
                            while(redOrBlue.equals("NO"));
                            MainActivity.sendMessage("join"+redOrBlue);
                        }
                    }.start();
                    break;
            }
        }
    }

}
